/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.bemanager.generatecomponent.componentgenerators;

import com.inspur.edp.bef.bemanager.codegenerator.JavaCompCodeNames;
import com.inspur.edp.bef.bemanager.generatecomponent.ComponentGenUtil;
import com.inspur.edp.bef.bizentity.operation.TccAction;
import com.inspur.edp.bef.bizentity.operation.internalmgraction.TccSettingElement;
import com.inspur.edp.bef.bizentity.util.StringUtil;
import com.inspur.edp.cdp.cdf.component.metadata.CommonComponentMetadata;
import com.inspur.edp.cdp.cdf.component.metadata.common.MetadataCreateStrategy;
import com.inspur.edp.cdp.cdf.component.metadata.common.MetadataHeaderInfo;
import com.inspur.edp.cdp.cdf.component.metadata.service.CommonComponentDtService;
import com.inspur.edp.component.schema.GspCompOperation;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataReference;
import io.iec.edp.caf.businessobject.api.entity.DevBasicBoInfo;
import io.iec.edp.caf.businessobject.api.service.DevBasicInfoService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.util.UUID;

public class TccActionComponentGenerator {

  public static TccActionComponentGenerator getInstance() {
    return new TccActionComponentGenerator();
  }

  public String generateComponent(TccSettingElement ele, String path, GspMetadata metadata,
      String objCode) {
    TccAction action = ele.getTccAction();
    CommonComponentDtService service = (CommonComponentDtService) SpringBeanUtils
        .getBean(CommonComponentDtService.class);
    if (StringUtil.checkNull(action.getComponentId())) {
      GspMetadata cmpMetadata = createComponent(ele, path, metadata.getHeader().getBizobjectID(),
          metadata.getHeader().getNameSpace(), objCode);
      // ③ 建立Action和元数据之间的关系
      action.setComponentId(cmpMetadata.getHeader().getId());
      action.setComponentName(cmpMetadata.getHeader().getName());
      MetadataReference tempVar = new MetadataReference();
      // ④ 添加元数据依赖
      tempVar.setMetadata(metadata.getHeader());
      tempVar.setDependentMetadata(cmpMetadata.getHeader());
      MetadataReference compReference = tempVar;
      metadata.getRefs().add(compReference);
      return action.getCode();
    }
    return null;
  }

  public GspMetadata createComponent(TccSettingElement ele, String path, String bizObjId,
      String objCode) {
    String namespace = ComponentGenUtil.getComponentAssemblyName(path);
    return createComponent(ele, path, bizObjId, namespace, objCode);
  }

  private GspMetadata createComponent(TccSettingElement ele, String path, String bizObjId,
      String namespace, String objCode) {
// ① 生成代码的动作需要重新赋值，兼容checkbe校验
    TccAction action = ele.getTccAction();
    CommonComponentDtService service = SpringBeanUtils.getBean(CommonComponentDtService.class);
    String newActionStr = evaluateBasicInfo(objCode, ele.getCode(), JavaCompCodeNames.TccAction);
    action.setCode(newActionStr);
    action.setName(newActionStr);
    // ② 生成构件
    CommonComponentMetadata ccmp = createCommonComponent(ele, bizObjId, objCode);
    MetadataHeaderInfo headerInfo = getMetadataHeaderInfo(bizObjId, namespace);
    GspMetadata cmpMetadata = service.create(headerInfo, ccmp, path, MetadataCreateStrategy.SKIP);
    if (cmpMetadata == null) {
      throw new RuntimeException("生成TCC构件异常");
    }
    return cmpMetadata;
  }

  private MetadataHeaderInfo getMetadataHeaderInfo(String bizObjId, String namespace) {
    MetadataHeaderInfo headerInfo = new MetadataHeaderInfo();
    headerInfo.setBizObjId(bizObjId);
    headerInfo.setNameSpace(namespace);
    return headerInfo;
  }

  private CommonComponentMetadata createCommonComponent(TccSettingElement ele, String bizObjId,
      String objCode) {
    String cmpCode = ele.getTccAction().getCode() + JavaCompCodeNames.TccActionControllerName;
    CommonComponentMetadata ccmp = new CommonComponentMetadata();
    DevBasicBoInfo info = SpringBeanUtils.getBean(DevBasicInfoService.class)
        .getDevBasicBoInfo(bizObjId);
    String suCode = info.getSuCode();
    String appCode = info.getAppCode();
    ccmp.setCode(cmpCode);
    ccmp.setName(cmpCode);
    ccmp.setApplication(appCode);
    ccmp.setServiceUnit(suCode);
    ccmp.setVersion("V1.0");
//    List<Operation> operations = new ArrayList<>();
//    operations.add(createDefaultOperation(ele));
    ccmp.addOperation(createDefaultOperation(ele));
    return ccmp;
  }

  private GspCompOperation createDefaultOperation(TccSettingElement ele) {
    GspCompOperation gspCompOperation = new GspCompOperation();
    gspCompOperation.setUri(UUID.randomUUID().toString());
    gspCompOperation.setCode(ele.getCode() + "Operation");
    gspCompOperation.setName(ele.getName() + "Operation");
    return gspCompOperation;
  }

  private String evaluateBasicInfo(String objCode, String actionCode, String suffixCode) {
    String suffix = String.format("%1$s%2$s%3$s", objCode, actionCode, suffixCode);
    return suffix;
  }
}
